﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSharpHelpers.TransferProtocols
{
    class ProtocolCSharp
    {
        public const int SourceType = 3;
        public const int DestinationType = 7;

        static Dictionary<string, string> cmdTable = new Dictionary<string, string>();
        static Dictionary<string, string> cmdLenTable = new Dictionary<string, string>();

        /// <summary>
        /// 信息头的长度
        /// </summary>
        /// <returns></returns>
        public static string BuildHeadLength()
        {
            return "{" + LTProtoBuffer.IntToString(4, 2) + "}{" + LTProtoBuffer.IntToString(1, 2) + "}"
                 + "{" + LTProtoBuffer.IntToString(4, 2) + "}{" + LTProtoBuffer.IntToString(1, 2) + "}"
                 + "{" + LTProtoBuffer.IntToString(4, 2) + "}";
        }

        /// <summary>
        /// 信息头的值
        /// </summary>
        /// <param name="CommandCode">命令码</param>
        /// <param name="TransferCode">传输码</param>
        /// <returns></returns>
        public static string BuildHeadValue(int CommandCode, int TransferCode)
        {
            return "{" + LTProtoBuffer.IntToString(SourceType, 4) + "}{0}"
                  + "{" + LTProtoBuffer.IntToString(DestinationType, 4) + "}{0}"
                  + "{" + LTProtoBuffer.IntToString(CommandCode, 4) + "}";
        }

        /// <summary>
        /// 转换协议消息
        /// </summary>
        public static List<string> TransferMessage(string message)
        {
            List<string> paramsList = TransferMessageToParamList(message);
            return paramsList;
        }

        /// <summary>
        /// 将string消息转换成List命令参数 
        /// </summary>
        private static List<string> TransferMessageToParamList(string message)
        {
            List<string> paramList = new List<string>();

            string[] arr = message.Split(',');

            string CommandCode = string.Empty;
            string TransferCode = string.Empty;
            string ParameterCount = string.Empty;

            int startIndex = 0;

            //先把CommandCode，TransferCode，ParameterCount提取出来
            for (int i = 0; i < arr.Length - 1; i++)
            {
                if (arr[i] == "7b")
                {
                    startIndex = i;
                    break;
                }
            }

            //通信格式为小端格式
            //CommandCode
            for (int i = 4; i > 0; i--)
            {
                CommandCode += arr[startIndex + i];
            }
            paramList.Add(CommandCode);
            startIndex = startIndex + 6;

            //TransferCode
            paramList.Add(arr[startIndex + 1]);
            startIndex = startIndex + 3;

            //ParameterCount
            for (int i = 2; i > 0; i--)
            {
                ParameterCount += arr[startIndex + i];
            }
            paramList.Add(ParameterCount);
            startIndex = startIndex + 4;

            int count = LTProtoBuffer.Change16To10(ParameterCount);

            //参数长度 
            List<int> paramLength = new List<int>();
            for (int i = 0; i < count; i++)
            {
                string strLen = string.Empty;
                for (int m = 2; m > 0; m--)
                {
                    strLen += arr[startIndex + i * 4 + m];
                }
                paramList.Add(strLen);
                paramLength.Add(LTProtoBuffer.Change16To10(strLen));
            }

            int ValueStartIndex = startIndex + count * 4;
            for (int i = 0; i < count; i++)
            {
                string strValue = string.Empty;
                for (int m = paramLength[i]; m > 0; m--)
                {
                    strValue += arr[ValueStartIndex + m];
                }
                paramList.Add(strValue);
                ValueStartIndex += (paramLength[i] + 2);
            }

            //将数字乱码转换成数字
            //paramList.RemoveAt(1);
            paramList = Change16To10Bit(paramList);

            return paramList;
        }

        /// <summary>
        /// 转换16进制到10进制
        /// </summary>
        /// <param name="messages"></param>
        /// <returns></returns>
        public static List<string> Change16To10Bit(List<string> messages)
        {
            string cmdcode = LTProtoBuffer.Change16To10(messages[0]).ToString();
            int paramNums = LTProtoBuffer.Change16To10(messages[2]);

            for (int i = 0; i < paramNums + 3; i++)
            {
                messages[i] = LTProtoBuffer.Change16To10(messages[i]).ToString();
            }
            messages[paramNums + 3] = LTProtoBuffer.Change16To10(messages[paramNums + 3]).ToString();
            messages[paramNums + 5] = LTProtoBuffer.Change16To10(messages[paramNums + 5]).ToString();

            for (int i = paramNums + 7; i < paramNums + 9; i++)
            {
                messages[i] = LTProtoBuffer.Change16To10(messages[i]).ToString();
            }

            //转换之前校验数据是否正确
            if (!IsDataValid(messages))
            {
                return null;
            }

            InitCmdTable();

            //后半部分 字符串转换成整数
            if (cmdTable.ContainsKey(cmdcode) && cmdTable[cmdcode] != string.Empty)
            {
                string[] ArrType = cmdTable[cmdcode].Split('|');

                //命令解析格式必须是“整型Binary|字符串ASCII|整型数组N*Binary”
                if (ArrType.Length == 3)
                {
                    if (!string.IsNullOrEmpty(ArrType[0]))
                    {
                        //处理整型
                        string[] changeindex = ArrType[0].Split(',');
                        for (int i = 0; i < changeindex.Length; i++)
                        {
                            int index = Convert.ToInt32(changeindex[i]);
                            int realindex = paramNums + 7 + index;
                            messages[realindex] = LTProtoBuffer.Change16To10(messages[realindex]).ToString();
                        }
                    }

                    if (!string.IsNullOrEmpty(ArrType[1]))
                    {
                        //处理ASCII
                        string[] changeindex = ArrType[1].Split(',');
                        for (int i = 0; i < changeindex.Length; i++)
                        {
                            int index = Convert.ToInt32(changeindex[i]);
                            int realindex = paramNums + 7 + index;
                            messages[realindex] = LTProtoBuffer.HexStringToAscii(messages[realindex]);
                        }
                    }

                    if (!string.IsNullOrEmpty(ArrType[2]))
                    {
                        //处理整型数组
                        string[] changeindex = ArrType[2].Split(',');
                        for (int i = 0; i < changeindex.Length; i++)
                        {
                            int index = Convert.ToInt32(changeindex[i]);
                            int realindex = paramNums + 7 + index;

                            //1102特殊处理，需要重构
                            if (messages[0] == "1102")
                            {
                                byte[] bt = LTProtoBuffer.StringTo16BitByLitteEndPoint(messages[realindex], Convert.ToInt32(messages[realindex + 1]));
                                messages[realindex] = LTProtoBuffer.ByteAcsiiToStringByCSharp(bt, Convert.ToInt32(messages[realindex + 1]));
                            }
                            else
                            {
                                messages[realindex] = LTProtoBuffer.Byte4BinaryToString(messages[realindex]);
                            }
                        }
                    }
                }
            }

            return messages;
        }



        public static bool IsDataValid(List<string> messages)
        {
            int COUNT = messages.Count;

            //检查参数的个数是否正确
            if (Convert.ToInt32(messages[2]) * 2 + 3 != COUNT)
            {
                return false;
            }

            //检查每个参数对应的长度是否正确
            //for (int i = 0; i < (COUNT - 3) / 2; i++)
            //{
            //    if (!(Convert.ToInt32(messages[i + 3]) == messages[i + 3 + Convert.ToInt32(messages[2])].Length) && !(Convert.ToInt32(messages[i + 3]) == 1) && !(Convert.ToInt32(messages[i + 3]) == 4) && !(Convert.ToInt32(messages[i + 3]) == 8))
            //    {
            //        return false;
            //    }
            //}

            return true;
        }


        /// <summary>
        /// 命令解析格式为“整型Binary|字符串ASCII|整型数组N*Binary”
        /// </summary>
        private static void InitCmdTable()
        {
            cmdTable.Clear();

            //用于ProtocolBusinessNew
            #region ProtocolBusiness

            cmdTable.Add("1101", "15,19||");
            cmdTable.Add("1102", "3||2");
            cmdTable.Add("1103", "2,3,4,5,6,7||");

            cmdTable.Add("1201", "10,17||");
            cmdTable.Add("1202", "2,3,4,5,6,7,8,9,10||11,12");
            cmdTable.Add("1203", "||2,3");

            cmdTable.Add("7001", "2,3,4||");
            cmdTable.Add("7002", "2||");
            cmdTable.Add("7003", "3,4||2");
            cmdTable.Add("7004", "3,4||2");
            cmdTable.Add("7005", "3,4||2");
            cmdTable.Add("7007", "2,3||");
            cmdTable.Add("7205", "2||");

            #endregion
        }
    }
}
